package com.lq.mode.singleton;

/**
 * @program: singleton-mode
 * @description: 懒汉单例模式双锁，提高效率，但不是绝对安全
 * @author: LQ
 * @create: 2019-11-07 22:57
 * 单例模式
 */

public class SingletonMode3 {
    private volatile static SingletonMode3 mode = null;

    /**
     * 单例模式,构造方法私有化
     */
    private SingletonMode3() {
    }

    /**
     * 获取单例模式的对象,加了锁，线程安全了，但是空间换时间，效率低
     *
     * @return
     */
    public static SingletonMode3 getMode() {
        if (mode == null) {
            // 同步块,线程安全的创建实例
            // synchronized在内部,在调用的时候是不需要加锁的,只有为空的时候才加锁
            synchronized (SingletonMode3.class) {
                if (mode == null) {
                    /*
                     * mode = new SingletonMode3();不是原子性操作
                     * 可能在a线程调用的时候,发现mode是空的,就进了if判断
                     * 但是jvm只声明了变量,有了一块空白的内存,还没有进行初始化
                     * 这个时候b线程调用了,发现不是null,直接返回,但是又没有初始化导致报错
                     */
                    mode = new SingletonMode3();
                }
            }
            mode = new SingletonMode3();
        }
        return mode;
    }
}
